package com.huo.util;

import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

@Component
public class UncompressFileTAR {


    //@Value("${hb.EXT:.tar.gz}")
    public String EXT = ".zip";

    private final Logger logger = LoggerFactory.getLogger(getClass());

    //@Value("${hb.fileRootPath:d:\\ftpdata\\}")
    public String fileRootPath = "G:\\BaiduNetdiskDownload\\20181001";

    public String decompressTar() {
        String filePath = isgz();
        if (filePath != null) {
            return decompress(filePath);
        }
        return null;
    }

    public String decompress(String pathname) {
        //check parameters
        File filed = new File(pathname);
        System.out.println("解压前的文件名称：" + pathname);
        if (!filed.exists() || !filed.getName().endsWith(EXT)) {
            return "";
        }
        String fileName = null;
        FileInputStream fis = null;
        ArchiveInputStream in = null;
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            fis = new FileInputStream(filed);
            GZIPInputStream is = new GZIPInputStream(new BufferedInputStream(fis));
            in = new ArchiveStreamFactory().createArchiveInputStream("tar", is);

            String outFileName = getFileName(pathname);
            bufferedInputStream = new BufferedInputStream(in);
            TarArchiveEntry entry = (TarArchiveEntry) in.getNextEntry();
            while (entry != null) {
                String name = entry.getName();
                String[] names = name.split("/");
                //System.out.println(names);
                fileName = outFileName;
                //System.out.println(fileName);
                for (int i = 0; i < names.length; i++) {
                    String str = names[i];
                    fileName = fileName + File.separator + str;
                }
                if (name.endsWith("/")) {
                    mkFolder(fileName);
                } else {
                    File file = mkFile(fileName);
                    System.out.println(fileName);
                    bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
                    int b = 0;
                    while ((b = bufferedInputStream.read()) != -1) {
                        bufferedOutputStream.write(b);
                    }
                    bufferedOutputStream.flush();
                    bufferedOutputStream.close();
                }
                entry = (TarArchiveEntry) in.getNextEntry();
            }

            System.out.println("解压后的文件名称：" + fileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ArchiveException e) {
            e.printStackTrace();
        } finally {
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                fis.close();
                in.close();
                filed.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return fileName;
    }

    private void mkFolder(String fileName) {
        File f = new File(fileName);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    private File mkFile(String fileName) {
        File f = new File(fileName);
        try {
            f.getParentFile().mkdirs();
            f.createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }

    public String getFileName(String f) {
       /* String fname = "";
        int i = f.lastIndexOf('.');

        if (i > 0 &&  i < f.length() - 1) {
            fname = f.substring(0,i-4);
        }
        return fname;*/
        String fname = "";
        int i = f.lastIndexOf(File.separator);

        if (i > 0 && i < f.length() - 1) {
            fname = f.substring(0, i);
        }
        return fname;
    }

    public String isgz() {
        File f = new File(fileRootPath);
        File[] files = f.listFiles();
        for (File file : files) {
            if (file.getName().endsWith(EXT)) {
                return file.getPath();
            }
        }
        return null;
    }

    public void unZipFiles(String filePath) {
        File f = new File(fileRootPath);
        File[] files = f.listFiles();
        for (File file : files) {
            if (file.getName().endsWith(".zip")) {
                unZipFile(file, "G:\\BaiduNetdiskDownload\\20181001\\");
            }
        }
    }


    public void unZipFile(File zipFile, String descDir) {

        try {
            File pathFile = new File(descDir);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }
            //解决zip文件中有中文目录或者中文文件
            ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
            for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String zipEntryName = entry.getName();
                InputStream in = zip.getInputStream(entry);
                String outPath = (descDir + zipEntryName).replaceAll("\\\\", "/");
                //判断路径是否存在,不存在则创建文件路径
                File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
                if (!file.exists()) {
                    file.mkdirs();
                }
                //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
                if (new File(outPath).isDirectory()) {
                    continue;
                }
                //输出文件路径信息
                System.out.println(outPath);
                OutputStream out = new FileOutputStream(outPath);
                byte[] buf1 = new byte[1024];
                int len;
                while ((len = in.read(buf1)) > 0) {
                    out.write(buf1, 0, len);
                }
                in.close();
                out.close();
            }
            zip.close(); //**原博忘记关了,所以我在做完这些操作后想要删除文件时,一直已占用,必须关掉服务器才可以**
            System.out.println("******************解压完毕********************");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String unZipFile(String filePath) {
        logger.info("解压文件开始：{}",filePath);
        if (filePath != null) {

            InputStream in = null;
            OutputStream out = null;
            String outPath = "";
            try {
                String descDir = filePath.substring(0, filePath.lastIndexOf("/")+1);
                File pathFile = new File(descDir);
                if (!pathFile.exists()) {
                    pathFile.mkdirs();
                }
                File zipFile = new File(filePath);
                //解决zip文件中有中文目录或者中文文件
                ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
                for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
                    ZipEntry entry = (ZipEntry) entries.nextElement();
                    String zipEntryName = entry.getName();
                    in = zip.getInputStream(entry);
                    outPath = (descDir + zipEntryName).replaceAll("\\\\", "/");
                    //判断路径是否存在,不存在则创建文件路径
                    File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
                    if (new File(outPath).isDirectory()) {
                        continue;
                    }
                    //输出文件路径信息
                    out = new FileOutputStream(outPath);
                    byte[] buf1 = new byte[1024];
                    int len;
                    while ((len = in.read(buf1)) > 0) {
                        out.write(buf1, 0, len);
                    }
                }
                zip.close(); //**原博忘记关了,所以我在做完这些操作后想要删除文件时,一直已占用,必须关掉服务器才可以**
                logger.info("解压文件结束：{}",outPath);
                return outPath;
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    in.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


    public static void main(String[] args) {
        File file = new File("G:\\BaiduNetdiskDownload\\20181001\\S01_CDFM21.zip");
        UncompressFileTAR uf = new UncompressFileTAR();
       /* String filePath = uf.isgz();
        if(filePath!= null){
            uf.decompress(filePath);
        }*/
        try {
            uf.unZipFiles("G:\\BaiduNetdiskDownload\\20181001\\");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}